import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';
import { message } from '@nbase/ui';
import { RESPONSE_CODE, type IResponse } from '@nbase/shared';
import { storage, StorageKey } from './storage';

// 导出共享类型
export type { IResponse, IPaginationResponse } from '@nbase/shared';

// 扩展 AxiosRequestConfig 接口
declare module 'axios' {
  interface AxiosRequestConfig {
    /**
     * 响应数据模式
     * - 'full': 返回完整的 AxiosResponse
     * - 'body': 返回 IResponse (包含 code, message, data, timestamp)
     * - 'data': 只返回 IResponse.data (默认)
     */
    _responseMode?: 'full' | 'body' | 'data';

    /**
     * 是否显示业务错误提示
     * - true: 自动显示错误 message (默认)
     * - false: 不显示，由调用方自行处理
     */
    _showBizErrorMsg?: boolean;
  }
}

/**
 * 创建 axios 实例
 */
const request = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000/api',
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json',
  },
});

/**
 * 请求拦截器
 */
request.interceptors.request.use(
  (config) => {
    // 从 storage 获取 token
    const token = storage.get<string>(StorageKey.AUTH_TOKEN);
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

/**
 * 响应拦截器
 */
request.interceptors.response.use(
  (response: AxiosResponse<IResponse>) => {
    const mode = response.config._responseMode || 'data';
    const showErrorMsg = response.config._showBizErrorMsg !== false;
    const { code, message: msg } = response.data;

    // 业务错误处理：HTTP 200 但 code ≠ 0
    if (code !== RESPONSE_CODE.SUCCESS) {
      // 根据配置决定是否自动显示错误提示
      if (showErrorMsg) {
        message.error(msg || '操作失败');
      }
      // 返回完整的业务错误信息，供调用方处理
      return Promise.reject({...response.data, isBizError: true });
    }

    // 成功响应，根据模式返回不同格式
    if (mode === 'full') {
      return response;
    } else if (mode === 'body') {
      return response.data as IResponse;
    }
    // 默认返回 IResponse.data
    return (response.data as IResponse).data as any;
  },
  (error: AxiosError<IResponse>) => {
    // 处理错误
    if (error.response) {
      const { status, data } = error.response;

      switch (status) {
        case RESPONSE_CODE.BAD_REQUEST:
          message.error(data?.message || '请求参数错误');
          break;
        case RESPONSE_CODE.UNAUTHORIZED:
          // 未授权，清除 token 并跳转到登录页
          storage.remove(StorageKey.AUTH_TOKEN);
          storage.remove(StorageKey.USER_INFO);
          window.location.href = '/login';
          message.error(data?.message || '登录已过期，请重新登录');
          break;
        case RESPONSE_CODE.FORBIDDEN:
          message.error(data?.message || '没有权限访问该资源');
          break;
        case RESPONSE_CODE.NOT_FOUND:
          message.error(data?.message || '请求的资源不存在');
          break;
        case RESPONSE_CODE.INTERNAL_ERROR:
          message.error(data?.message || '服务器错误');
          break;
        default:
          message.error(data?.message || '请求失败');
      }
    } else if (error.request) {
      message.error('网络错误，请检查网络连接');
    } else {
      message.error('请求配置错误');
    }

    return Promise.reject(error);
  }
);

export default request;

/**
 * GET 请求
 */
export function get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
  return request.get(url, config);
}

/**
 * POST 请求
 */
export function post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
  return request.post(url, data, config);
}

/**
 * PUT 请求
 */
export function put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
  return request.put(url, data, config);
}

/**
 * DELETE 请求
 */
export function del<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
  return request.delete(url, config);
}

/**
 * PATCH 请求
 */
export function patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
  return request.patch(url, data, config);
}

